package com.prism.cluster;

import java.util.ArrayList;
import com.prism.moodme.data.Data;

class Cluster {

	private ArrayList<Data> members;
	private Data centroid;

	/**
	 * Cluster class takes a set of data and calculates
	 * new centroid by finding the mean Data.
	 * @param members
	 */
	public Cluster(ArrayList<Data> members){

//		Set<Data> docs = new TreeSet<Data>(members);
//		Collections.sort(members);
		setMembers(members);
		centroid();
//		System.out.println("new cluster: "+this);
	}

	public Cluster(){
		setMembers(new ArrayList<Data>());
	}

	public void add(Data doc){
		getMembers().add(doc);
	}


	public boolean equals(Object object){
		if(!(object instanceof Cluster))
			return false;
		Cluster other = (Cluster)object;
		if((this.getCentroid().equals(other.getCentroid()))&&this.size() == other.size())
			return true;
		return false;

	}
//	private void setMinDist(){
//		for(Data doc : getMembers()){
//			doc.setMinCentroid(Utility.distance(doc, getCent()));
//		}
//	}


	private void centroid(){
		if(size() == 1){
			setCentroid(getMembers().get(0));
			return;
		}

		Data centroid;
		ArrayList<Double> avg = new ArrayList<Double>();

		for(int i=0; i<getMembers().get(0).size(); i++){
			avg.add(average(i));
		}
//		System.out.println(avg);

		centroid = getClosest(new Data(avg));
		setCentroid(centroid);

	}


	private Data getClosest(Data avg) {
		Data centroid = getMembers().get(0);

		double min = getMembers().get(0).euclid(avg);
//		System.out.println(min);
		for(Data data : getMembers()){
			double dist = data.euclid(avg);
			if(min>dist){
//				System.out.println("New Minimum distance: "+dist);
				min = dist;
				centroid = data;
			}
		}
	return centroid;
}

	public double average(int feature){
		double avg = 0.0;
		assert(feature < getMembers().get(0).size());
		for(Data dat : getMembers())
			avg += dat.getFeature(feature);

		return avg/size();
	}

	private void setMembers(ArrayList<Data> members) {
		this.members =  members;
	}

	public ArrayList<Data> getMembers() {
		return members;
	}

	public int size(){
		return getMembers().size();
	}

	public int hashCode(){
		String code = getCentroid().getDataID() + size();
		return code.hashCode();
	}

	public String toString(){
		StringBuilder sb = new StringBuilder();
		sb.append("size: ");
		sb.append(size());
		sb.append("\t");
		sb.append("centroid: ");
		sb.append(getCentroid());
//		sb.append("\n");
//		sb.append(getMembers());
		return sb.toString();
	}

	public void setCentroid(Data centroid) {
		this.centroid = centroid;
	}

	public Data getCentroid() {
		return centroid;
	}


	public String getCode() {
		return getCentroid().getDataID();
	}

	public boolean equals(Cluster other){
//		System.out.println("cent: "+getCentroid().equals(other.getCentroid()));
//		System.out.println("size: "+ (size()==other.size()));
		return getCentroid().equals(other.getCentroid()) && size()==other.size();
	}

}
